home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Pascal Super Library
/
Pascal Super Library (CW International)(1997).bin
/
DIALOGS
/
JANUSW
/
DIALOGWN.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1994-11-14
|
33KB
|
981 lines
Unit DialogWn;
{ Unit: DialogWn
Version: 1.33
Purpose: make a descendant of tWindow named tDialogWindow that behaves like
a modeless or modal dialog.
Developer: Peter Sawatzki (ps)
Buchenhof 3, D58091 Hagen, Germany
CompuServe: 100031,3002
Date: Author:
04/22/92 ps initial release by ps
07/25/92 ps/jwp added Scroller support
08/01/92 ps added RunModal and modal support
08/12/92 ps removed SetClassName and NewClass, fixed bug in MDI support
08/14/92 ps fixed Focus problems in MDI, give focus to first ws_TabStop child
08/30/92 ps fixed more focus problems in MDI, added SysModal support
09/27/92 ps call DefDlgProc to support DropDownBoxes and Multiline edit controls
10/21/92 ps some changes for new OWL
01/28/93 ps add LoadMenu for automatic menu load
02/06/93 ps add support for InitResource, fix BWCC's WM_NCCREATE glitch
06/10/93 ps added CanClose method to cancel modal dialogs
06/15/93 dob removed CanClose, added WMQueryEndSession
06/17/93 dob/ps added wmKillFocus and wmNCActivate methods, modified wmSetFocus method
06/29/93 ps added tAdvApplication object to resolve focus problems
07/01/93 ps added tAdvMdiWindow object to solve MessageBox problem
07/05/93 ps added hEditBuffer to save system resources for Edit Ctls
07/23/93 ps added wm_EnterIdle sending to RunModal
08/10/93 ps fixed ListBox focus problem
08/28/93 ps added dm_SetDefId and dm_GetDefId handling
08/30/93 ps added calls to DefDialogProc() for proper default PushButton handling
09/02/93 ps included tJanusDialogWindow properties in tDialogWindow
09/11/93 ps added Ctl3D support
10/01/93 ps added use of DynLink to DYNAMICALLY link DLLs
10/15/93 ps added focus autofollow
12/10/93 ps added BorDlg_Gray support
01/01/94 ms/ps fixed Ctl-Tab bug in wmSysCommand, change wmSetFocus
01/01/94 ps remove all calls to DefDlgProc, do all DefDlg stuff in tDialogWindow
01/21/94 ps fix bug in resource parsing when menuname is an integer atom of form #$xx00
02/14/94 ps added support for VBX control
03/03/94 ps fix OWL wm_Activate bug
03/14/94 pl/ps make MapDialogRect compatible
08/01/94 ps/sm added wm_GetFont, better values for XLine/YLine,
remove calls to BWCC.DefWndProc, remove wmPaint
Contributing: Jeroen W. Pluimers (jwp)
Dan O. Butler (dob) [72134,633]
Andy Cook [71331,501]
Dean Wyant [75110,3253]
Max Stempfhuber (ms) [100140,2034]
Per Larsen (pl) [100121,1514]
Sebastian Modersohn [100340,1474]
Copyright (c) 1994 Peter Sawatzki. All Rights Reserved.
}
{$A+,B-,F-,G+,I-,K+,P-,Q-,R-,S-,T-,V-,X+}
Interface
Uses
DynLink,
Vbx,
WinTypes,
Win31,
{$IfDef Custom}
CustomWn,
{$EndIf}
{$IfDef Debug}
Debug,
{$EndIf}
Objects,
oWindows;
Const
wm_EnterMenuLoop = $0211; {undocumented}
MdiS_AllChildStyles = $0001;
{-private message for tDialogWindow}
wm_TrackFocus = (wm_User+3);
{-style bits for DlgStyle}
OrgStyle = $00;
ForceStd = $01; {Force BorDlgs to appear as Std dialogs}
ForceBor = $02; {Force Std dialogs to appear as BorDlgs}
EnableCtl3D= $04; {Enable Ctl3D}
ForceGrayBk= $08; {Force a gray background}
GrayBorDlg = $10; {gray Borland dialogs}
DefStyle: Word = OrgStyle Or EnableCtl3D Or ForceGrayBk; {use OrgStyle by default}
DefCtl3DStyle: LongInt = Ctl3D_All;
DefFontWeight: Integer = fw_Bold; {standard Windows behaviour}
Type
tChildClass = Record
wX, wY, wCX, wCY: Integer;
wID: Word;
dwStyle: LongInt;
szClass: Array[0..63] Of Char;
szTitle: Array[0..131] Of Char;
CtlDataSize: Byte;
CtlData: Array[0..255] Of Byte;
End;
tDialogWindowAttr = Record
Name: pChar;
ItemCount: Integer;
MenuName,
ClassName,
FontName: pChar;
Font: hFont;
FontWeight: Integer;
PointSize: Integer;
DlgItems: Pointer; {only valid ...}
VbInfo: Pointer; {... during Create}
ResW, {dialogs initial width ...}
ResH: Integer; {... and height}
wUnitsX,
wUnitsY: Word;
hEditBuffer: tHandle;
End;
{$IfDef Custom}
Ancestor = tCustomWindow;
{$Else}
Ancestor = tWindow;
{$EndIf}
pDialogWindow = ^tDialogWindow;
tDialogWindow = Object(Ancestor)
DialogAttr: tDialogWindowAttr;
ModalCode: pInteger;
DlgStyle: Word;
Ctl3DStyle: LongInt;
DefId: hWnd;
IsBorDlg: Boolean;
Constructor Init (aParent: pWindowsObject; aName: pChar);
Constructor InitCustom (aParent: pWindowsObject; aName: pChar; aDlgStyle: Word);
Destructor Done; Virtual;
Procedure AllocateEditBuffer; Virtual;
Function Create: Boolean; Virtual;
Procedure Destroy; Virtual;
Procedure SetupWindow; Virtual;
Function GetClassName: pChar; Virtual;
Procedure GetWindowClass (Var aWndClass: tWndClass); Virtual;
Procedure GetChildClass (Var aChildClass: tChildClass); Virtual;
Procedure MangleChildClass (Var aChildClass: tChildClass); Virtual;
Function CreateDialogChild ({Bp7.01: Const} Var aChildClass: tChildClass): hWnd; Virtual;
Function CreateDialogChildren: Boolean; Virtual;
Procedure CreateDialogFont;
Procedure GetDialogInfo (aPtr: Pointer);
Procedure StoreDMInfo;
Procedure UpdateDialog; Virtual;
Procedure MangleClass; Virtual;
Function RunModal: Integer; Virtual;
Function IsModal: Boolean;
Procedure EndDlg (aRetValue: Integer); Virtual;
Function GetItemHandle (DlgItemID: Integer): hWnd;
Function SendDlgItemMsg (DlgItemID: Integer; aMsg, wParam: Word; lParam: LongInt): LongInt;
Procedure Ok (Var Msg: tMessage); Virtual id_First+id_Ok;
Procedure Cancel (Var Msg: tMessage); Virtual id_First+id_Cancel;
Procedure wmClose (Var Msg: tMessage); Virtual wm_First+wm_Close;
Procedure wmQueryEndSession (Var Msg: tMessage); Virtual wm_First+wm_QueryEndSession;
Procedure wmSize (Var Msg: tMessage); Virtual wm_First+wm_Size;
Procedure wmLButtonDown (Var Msg: tMessage); Virtual wm_First+wm_LButtonDown;
Procedure wmNcLButtonDown (Var Msg: tMessage); Virtual wm_First+wm_NcLButtonDown;
Procedure wmEnterMenuLoop (Var Msg: tMessage); Virtual wm_First+wm_EnterMenuLoop;
Procedure wmActivate (Var Msg: tMessage); Virtual wm_First+wm_Activate;
Procedure HideComboListBox;
Procedure wmNextDlgCtl (Var Msg: tMessage); Virtual wm_First+wm_NextDlgCtl;
Procedure dmGetDefId (Var Msg: tMessage); Virtual wm_First+dm_GetDefId;
Procedure wmGetFont (Var Msg: tMessage); Virtual wm_First+wm_GetFont;
Procedure wmTrackFocus (Var Msg: tMessage); Virtual wm_First+wm_TrackFocus;
Procedure wmSetFocus (Var Msg: tMessage); Virtual wm_First+wm_SetFocus;
Procedure wmCtlColor (Var Msg: tMessage); Virtual wm_First+wm_CtlColor;
Procedure wmEraseBkGnd (Var Msg: tMessage); Virtual wm_First+wm_EraseBkGnd;
Procedure wmVbxFireEvent (Var Msg: tMessage); Virtual wm_First+wm_VbxFireEvent;
Procedure DefaultEventProc (Var Event: tVbxEvent); Virtual;
End;
pAdvApplication = ^tAdvApplication;
tAdvApplication = Object(tApplication)
Function ProcessDlgMsg (Var Message: tMsg): Boolean; Virtual;
Function ProcessAppMsg (Var Message: tMsg): Boolean; Virtual;
End;
pAdvMdiWindow = ^tAdvMdiWindow;
tAdvMdiWindow = Object(tMdiWindow)
Procedure wmActivate (Var Msg: tMessage); Virtual wm_First+wm_Activate;
End;
Function ExecDialogWindow (aDialogWindow: pDialogWindow): Integer;
Implementation
Uses
WinProcs,
Strings;
Const
sztDialogWindow = 'tDialogWindow';
ws_MdiChild = ws_Child Or ws_ClipSiblings Or ws_SysMenu Or ws_Caption Or
ws_ThickFrame Or ws_MinimizeBox Or ws_MaximizeBox Or ws_Visible;
ws_MdiAllowed = ws_MdiChild Or ws_Minimize Or ws_Maximize Or ws_ClipChildren Or
ws_Disabled Or ws_HScroll Or ws_VScroll Or ws_ThickFrame Or $FFFF;
{dialog window words}
dwl_MsgResult = 0;
dwl_DlgProc = 4;
dwl_User = 8;
dww_wUnitsX = 12;
dww_wUnitsY = 14;
dww_hWndFocusSave = 16;
dww_fEnd = 18; {DM's flag for end dialog}
dww_Result = 22; {default id and dialog result}
dww_hData = 24; {handle to edit memory block}
dww_hUserFont = 26; {handle to dialog font}
Function DlgToClientX (x, Units: Integer): Integer;
{DlgToClientX:= x*Units Div 4}
Inline($59/$58/ {Pop Cx Ax}
$F7/$E1/ {Mul Cx}
$D1/$E8/ {Shr Ax,1}
$D1/$E8); {Shr Ax,1}
Function DlgToClientY (y, Units: Integer): Integer;
{DlgToClientY:= y*Units Div 8}
Inline($59/$58/ {Pop Cx Ax}
$F7/$E1/ {Mul Cx}
$D1/$E8/ {Shr Ax,1}
$D1/$E8/ {Shr Ax,1}
$D1/$E8); {Shr Ax,1}
Constructor tDialogWindow.Init (aParent: pWindowsObject; aName: pChar);
Begin
Inherited Init(aParent,sztDialogWindow); {fake title}
FillChar(DialogAttr,SizeOf(DialogAttr),0);
ModalCode:= Nil; {assume modeless window}
DlgStyle:= DefStyle; {assume default style}
Ctl3DStyle:= DefCtl3DStyle;
IsBorDlg:= False; {really unknown at this moment}
DefId:= 0;
With DialogAttr Do Begin
hEditBuffer:= 0; {no edit buffer allocated yet}
FontWeight:= DefFontWeight; {Windows standard dialogs are bold}
If PtrRec(aName).Seg=0 Then Name:= aName Else Name:= StrNew(aName)
End
End;
Constructor tDialogWindow.InitCustom (aParent: pWindowsObject; aName: pChar; aDlgStyle: Word);
Begin
tDialogWindow.Init (aParent, aName); {very important to use 'tDialogWindow.' !!!}
DlgStyle:= aDlgStyle
End;
Destructor tDialogWindow.Done;
Begin
With DialogAttr Do Begin
If PtrRec(Name).Seg<>0 Then StrDispose(Name);
If PtrRec(MenuName).Seg<>0 Then StrDispose(MenuName);
StrDispose(ClassName);
StrDispose(FontName)
End;
Inherited Done
End;
Procedure tDialogWindow.AllocateEditBuffer;
{-allocate a local heap for edit controls}
Begin
DialogAttr.hEditBuffer:= GlobalAlloc(GHnd, 4096)
End;
Function tDialogWindow.Create: Boolean;
Var
aRes, VbRes: tHandle;
Begin
Create:= False;
If (Status<>0) Or (DialogAttr.Name=Nil) Then
Exit;
aRes:= FindResource(hInstance, DialogAttr.Name, rt_Dialog);
If aRes<>0 Then
aRes:= LoadResource(hInstance, aRes);
If aRes=0 Then
Status:= em_InvalidWindow
Else Begin
If Assigned(ModalCode) Then Begin
If Assigned(Parent) Then
EnableWindow(Parent^.hWindow, False); {disable Parent}
ModalCode^:= 0 {begin modal state}
End;
VbRes:= FindResource(hInstance, DialogAttr.Name, rt_DlgInit);
If VbRes<>0 Then Begin
VbRes:= LoadResource(hInstance, VbRes);
DialogAttr.VbInfo:= LockResource(VbRes)
End;
GetDialogInfo(LockResource(aRes));
If Assigned(DialogAttr.MenuName) Then
Attr.Menu:= LoadMenu(hInstance, DialogAttr.MenuName);
CreateDialogFont;
UpdateDialog;
MangleClass;
EnableKBHandler;
Create:= Inherited Create;
UnlockResource(aRes);
FreeResource(aRes);
If VbRes<>0 Then Begin
UnlockResource(VbRes);
FreeResource(VbRes)
End
End
End;
Procedure tDialogWindow.Destroy;
Begin
If Assigned(ModalCode) Then Begin
If Assigned(Parent) Then
EnableWindow(Parent^.hWindow,True); {enable Parent}
If ModalCode^=0 Then {terminate modal window if not already terminated}
ModalCode^:= id_Cancel
End;
Inherited Destroy;
With DialogAttr Do Begin
If Assigned(FontName) Then
DeleteObject(Font);
If hEditBuffer<>0 Then
hEditBuffer:= GlobalFree(hEditBuffer)
End;
End;
Procedure tDialogWindow.SetupWindow;
Begin
StoreDMInfo;
SendMessage(hWindow,wm_SetFont,DialogAttr.Font,0);
If Not CreateDialogChildren Then
Status:= em_InvalidChild;
Inherited SetupWindow
End;
(*Procedure tDialogWindow.wmPaint(Var Msg: tMessage);
Var
PaintInfo: tPaintStruct;
aRect: tRect;
Begin
PaintInfo.hDC:= GetDC(hWindow); {BeginPaint does not do the job}
GetClientRect(hWindow, PaintInfo.rcPaint);
If Assigned(Scroller) Then Scroller^.BeginView(PaintInfo.hDC, PaintInfo);
Paint(PaintInfo.hDC, PaintInfo);
If Assigned(Scroller) Then Scroller^.EndView;
ReleaseDC(hWindow, PaintInfo.hDC);
DefWndProc(Msg)
End;
*)
Function tDialogWindow.GetClassName: pChar;
Begin
If Assigned(DialogAttr.ClassName) Then
GetClassName:= DialogAttr.ClassName
Else
GetClassName:= wc_Dialog
End;
Procedure tDialogWindow.GetWindowClass (Var aWndClass: tWndClass);
Begin
Inherited GetWindowClass(aWndClass);
aWndClass.cbWndExtra:= DlgWindowExtra
End;
Procedure tDialogWindow.GetChildClass (Var aChildClass: tChildClass);
{-change a childs window class. Standard windows behaviour is simulated here:
change special resource shortcuts (#$80..#$85) to their appropriate class names}
Const
PreDefClasses: Array[#$80..#$85] Of pChar =
('Button','Edit','Static','ListBox','ScrollBar','ComboBox');
Begin
MangleChildClass(aChildClass);
With aChildClass Do
Case szClass[0] Of
#$80..#$85: StrCopy(szClass,PreDefClasses[szClass[0]])
End
End;
Procedure tDialogWindow.MangleChildClass (Var aChildClass: tChildClass);
Begin With aChildClass Do Begin
If DlgStyle And ForceBor<>0 Then Begin
If szClass[0]=#$80 Then
Case dwStyle And $F Of
bs_CheckBox,
bs_AutoCheckBox: StrCopy(szClass,BorCheck);
bs_RadioButton..bs_Auto3State,
bs_AutoRadioButton: StrCopy(szClass,BorRadio);
bs_GroupBox: StrCopy(szClass,BorShade);
End
End Else
If DlgStyle And ForceStd<>0 Then Begin
If (StrIComp(szClass,BorCheck)=0)
Or (StrIComp(szClass,BorRadio)=0)
Or (StrIComp(szClass,BorButton)=0) Then szClass[0]:= #$80
Else If (StrIComp(szClass,BorShade)=0) Then
Case dwStyle And $F Of
bss_Group: Begin szClass[0]:= #$80; dwStyle:= (dwStyle And $FFFF0FF0) Or bs_GroupBox End;
bss_Hdip,
bss_Hbump,
bss_Vdip,
bss_Vbump: Begin szClass[0]:= #$82; dwStyle:= (dwStyle And $FFFFFFF0) Or ss_BlackRect End;
End
End
End End;
Function tDialogWindow.CreateDialogChild ({Bp7.01: Const} Var aChildClass: tChildClass): hWnd;
Var
aCtl: hWnd;
lpDlgItemInfo: Pointer;
Inst: tHandle;
Begin
With DialogAttr, aChildClass Do Begin
If CtlDataSize=0 Then
lpDlgItemInfo:= Nil
Else
lpDlgItemInfo:= @CtlData;
Inst:= System.hInstance;
If (Attr.Style And ds_LocalEdit=0) And (StrIComp(szClass, 'Edit')=0) Then Begin
If hEditBuffer=0 Then
AllocateEditBuffer;
If hEditBuffer<>0 Then
Inst:= hEditBuffer
End;
If StrIComp(szClass,'VBControl')=0 Then
aCtl:= dVbx.CreateControl(hWindow, wId, szTitle, dwStyle,
DlgToClientX(wX,wUnitsX), DlgToClientY(wY,wUnitsY),
DlgToClientX(wCX,wUnitsX), DlgToClientY(wCY,wUnitsY),
VbInfo)
Else Begin
aCtl:= CreateWindowEx(ws_Ex_NoParentNotify, szClass, szTitle, dwStyle,
DlgToClientX(wX,wUnitsX), DlgToClientY(wY,wUnitsY),
DlgToClientX(wCX,wUnitsX), DlgToClientY(wCY,wUnitsY),
hWindow, wID, Inst,
lpDlgItemInfo);
If aCtl<>0 Then Begin
If Inst=hEditBuffer Then
SendMessage(aCtl, em_LimitText, 0, 0);
SendMessage(aCtl, wm_SetFont, Font, 0)
End
End;
{$IfDef Debug}
If (aCtl=0) Or Not IsWindow(aCtl) Then
WriteLn('err DialogWn: CreateDialogChild failed! Class= ',
StrPasEx(szClass),' Title=', StrPasEx(szTitle));
{$EndIf}
CreateDialogChild:= aCtl
End
End;
Function tDialogWindow.CreateDialogChildren: Boolean;
Var
i: Integer;
aPtr: pChar;
anItem: tChildClass;
aCtl: hWnd;
Begin
CreateDialogChildren:= False;
aPtr:= DialogAttr.DlgItems;
With DialogAttr, anItem Do
For i:= 1 To DialogAttr.ItemCount Do Begin
{-copy fixed header and first byte of szClass}
Move(aPtr^,anItem,15); Inc(Word(aPtr),15);
Case szClass[0] Of
#$80..#$85: szClass[1]:= #0; {be safe}
Else
StrCopy(szClass+1, aPtr); {copy rest of classname}
Inc(Word(aPtr),StrLen(aPtr)+1)
End;
If aPtr^=#255 Then Begin {fiddle with Caption as a number}
Str(pWord(aPtr+1)^, szTitle); {convert to '#xxx' form}
Move(szTitle[0], szTitle[1], StrLen(szTitle)+1);
szTitle[0]:= '#';
Inc(Word(aPtr), SizeOf(Byte)+SizeOf(Word))
End Else Begin
StrCopy(szTitle,aPtr);
Inc(Word(aPtr),StrLen(aPtr)+1)
End;
Move(aPtr^,CtlDataSize,Byte(aPtr^)+1);
Inc(Word(aPtr),CtlDataSize+1);
{-give descendants a chance to change child class}
GetChildClass(anItem);
aCtl:= CreateDialogChild(anItem);
If aCtl<>0 Then Begin
If (dwStyle And ws_TabStop<>0) And (FocusChildHandle=0) Then
FocusChildHandle:= aCtl; {set focus to first tab ctl}
If (dwStyle And bs_DefPushButton<>0)
And (SendMessage(aCtl, wm_GetDlgCode, 0, 0) And DlgC_DefPushButton<>0) Then
DefId:= wId
End
End;
{-subclass the dialog for Ctl3D}
If DlgStyle And EnableCtl3D<>0 Then
dCtl3D.SubClassDlgEx(hWindow, Ctl3DStyle);
If (DefId=0) And (GetDlgItem(hWindow, 1)<>0) Then
DefId:= 1; {Windows forces the Ok button to be the default button}
If DefId<>0 Then
SendMessage(GetDlgItem(hWindow, DefId), bm_SetStyle, bs_DefPushButton, 0); {so let the buttons style reflect this}
DialogAttr.DlgItems:= Nil; {no longer valid}
CreateDialogChildren:= True
End;
Procedure tDialogWindow.GetDialogInfo (aPtr: Pointer);
Begin
With Attr,DialogAttr Do Begin
Style:= LongInt(aPtr^); Inc(Word(aPtr),SizeOf(LongInt));
ItemCount:= Byte(aPtr^); Inc(Word(aPtr),SizeOf(Byte));
If Not IsFlagSet(wb_MdiChild) Then
X:= Integer(aPtr^); Inc(Word(aPtr),SizeOf(Integer));
Y:= Integer(aPtr^); Inc(Word(aPtr),SizeOf(Integer));
W:= Integer(aPtr^); Inc(Word(aPtr),SizeOf(Integer));
H:= Integer(aPtr^); Inc(Word(aPtr),SizeOf(Integer));
If Byte(aPtr^)=255 Then Begin
MenuName:= pChar(pWord(pChar(aPtr)+1)^); {<g>}
Inc(Word(aPtr), SizeOf(Byte)+SizeOf(Word))
End Else Begin
MenuName:= StrNew(aPtr);Inc(Word(aPtr),StrLen(aPtr)+1)
End;
ClassName:= StrNew(aPtr); Inc(Word(aPtr),StrLen(aPtr)+1);
Title:= StrNew(aPtr); Inc(Word(aPtr),StrLen(aPtr)+1);
If Style And ds_SetFont>0 Then Begin
PointSize:= Integer(aPtr^); Inc(Word(aPtr),SizeOf(Integer));
FontName:= StrNew(aPtr); Inc(Word(aPtr),StrLen(aPtr)+1)
End Else Begin
PointSize:= 0;
FontName:= Nil
End;
If Style And ds_ModalFrame>0 Then
ExStyle:= ExStyle Or ws_Ex_DlgModalFrame;
DlgItems:= aPtr
End
End;
Procedure tDialogWindow.StoreDMInfo;
{store information in window extra words to be dialog manager compatible}
Begin
SetWindowLong(hWindow, dwl_DlgProc, GetWindowLong(hWindow, gwl_WndProc)); {CTL3D compatible}
SetWindowWord(hWindow, dww_wUnitsX, DialogAttr.wUnitsX); {satisfy MapDialogRect}
SetWindowWord(hWindow, dww_wUnitsY, DialogAttr.wUnitsY); {satisfy MapDialogRect}
End;
Procedure tDialogWindow.UpdateDialog;
{-update and resize dialog window according to its style}
Var
TheMDIClient: pMdiClient;
aRect: tRect;
Begin With Attr, DialogAttr Do Begin
{-update style bits for MDI}
If isFlagSet(wb_MdiChild) Then Begin
TheMDIClient:= Parent^.GetClient;
{-check if the Client window has the MdiS_AllChildStyles bit set}
If (TheMDIClient=Nil)
Or (GetWindowLong(TheMDIClient^.hWindow, gwl_Style) And MdiS_AllChildStyles=0) Then
Style:= ws_MdiChild
Else
Style:= Style And ws_MdiAllowed Or ws_Child {reject disallowed styles}
End Else
If Style And (ws_PopUp+ws_ThickFrame)=ws_PopUp+ws_ThickFrame Then
ExStyle:= ExStyle And Not ws_Ex_DlgModalFrame; {correct Windows bug}
{-reject invisible modal window}
If Assigned(ModalCode) Then
Attr.Style:= Attr.Style Or ws_Visible;
{-resize the window according to its style and size}
SetRect(aRect, 0, 0, DlgToClientX(w, wUnitsX), DlgToClientY(h, wUnitsY));
AdjustWindowRectEx(aRect, Style, Menu<>0, ExStyle);
w:= aRect.right-aRect.left;
h:= aRect.bottom-aRect.top;
ResW:= w;
ResH:= h
End End;
Procedure tDialogWindow.MangleClass;
Var
szClass: Array[0..63] Of Char;
ClassIsBorDlg: Boolean;
Begin
{-if we can't find Ctl3D, disable it's usage}
If (DlgStyle And EnableCtl3D<>0) And Not dCtl3D.LibLink Then
DlgStyle:= DlgStyle And Not EnableCtl3D;
ClassIsBorDlg:= Assigned(DialogAttr.ClassName) And
(StrLIComp(DialogAttr.ClassName, BorDialog, Length(BorDialog))=0);
If ClassIsBorDlg And (StrLIComp(DialogAttr.ClassName, BorDialogGray, Length(BorDialogGray))=0) Then
DlgStyle:= DlgStyle Or GrayBorDlg;
{-load BWCC if the dialog needs to be a BorDlg}
If ClassIsBorDlg Or (DlgStyle And ForceBor<>0) Then
If Not dBWCC.LibLink Then {force std dialogs if BWCC can not be loaded}
DlgStyle:= DlgStyle Or ForceStd And Not ForceBor;
If DlgStyle And (ForceStd Or ForceBor)<>0 Then With DialogAttr Do Begin
If DlgStyle And ForceBor<>0 Then
StrCopy(szClass, BorDialog)
Else
szClass[0]:= #0;
If ClassIsBorDlg Then
StrCat(szClass, ClassName+Length(BorDialog))
Else
StrCat(szClass, ClassName);
StrDispose(ClassName);
ClassName:= StrNew(szClass)
End;
IsBorDlg:= Assigned(DialogAttr.ClassName) And (StrLIComp(DialogAttr.ClassName, BorDialog, Length(BorDialog))=0)
End;
Procedure tDialogWindow.CreateDialogFont;
{-create the dialog font and calculate dialog units based on font}
Const
aWidthString = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
Var
aDC: hDC;
anOldFont: hFont;
aLogFont: tLogFont;
aTextMetric: tTextMetric;
Begin With DialogAttr Do Begin
aDC:= GetDC(0);
If FontName=Nil Then
Font:= GetStockObject(System_Font)
Else Begin
FillChar(aLogFont,SizeOf(aLogFont),0);
With aLogFont Do Begin
StrCopy(lfFaceName,FontName);
lfHeight:= -MulDiv(DialogAttr.PointSize,GetDeviceCaps(aDC, LogPixelsY),72);
lfWeight:= FontWeight
End;
Font:= CreateFontIndirect(aLogFont)
End;
anOldFont:= SelectObject(aDC, Font);
GetTextMetrics(aDC, aTextMetric);
{-use the Microsoft recommended method to retrieve average width}
wUnitsX:= (Word(GetTextExtent(aDC, aWidthString, Length(aWidthString)))
Div (Length(aWidthString) Div 2) + 1) Div 2;
wUnitsY:= aTextMetric.tmHeight;
SelectObject(aDC, anOldFont);
ReleaseDC(0, aDC)
End End;
Function tDialogWindow.RunModal: Integer;
Var
aMsg: tMsg;
ReturnCode: Integer;
IdleParent: tHandle;
Begin
ReturnCode:= 0;
ModalCode:= @ReturnCode; {Trick OWL}
SetFlags(wb_MDIChild, False);
Create;
If Status<>0 Then Begin
RunModal:= Status;
Exit
End;
If Attr.Style And ds_SysModal>0 Then
SetSysModalWindow(hWindow); {support SysModal dialogs as well}
If Attr.Style And ds_NoIdleMsg>0 Then
IdleParent:= 0
Else
IdleParent:= GetParent(hWindow);
Repeat
If PeekMessage(aMsg, 0, 0, 0, pm_Remove) Then Begin
If IdleParent<>0 Then
SendMessage(IdleParent, wm_EnterIdle, MsgF_DialogBox, hWindow);
If Not Application^.ProcessDlgMsg(aMsg) Then Begin
TranslateMessage(aMsg);
DispatchMessage(aMsg)
End
End
Until ReturnCode<>0; {until window is no longer modal}
Free;
RunModal:= ReturnCode
End;
Function tDialogWindow.IsModal: Boolean;
Begin
IsModal:= Assigned(ModalCode)
End;
Procedure tDialogWindow.EndDlg (aRetValue: Integer);
Begin
If Assigned(ModalCode) Then {set return code if it's a modal window}
ModalCode^:= aRetValue
Else
CloseWindow
End;
Function tDialogWindow.GetItemHandle (DlgItemID: Integer): hWnd;
Begin
GetItemHandle:= GetDlgItem(hWindow, DlgItemID)
End;
Function tDialogWindow.SendDlgItemMsg (DlgItemID: Integer; aMsg, wParam: Word; lParam: LongInt): LongInt;
Begin
SendDlgItemMsg:= SendDlgItemMessage(hWindow, DlgItemID, AMsg, WParam, LParam)
End;
Procedure tDialogWindow.Ok (Var Msg: tMessage);
Begin
If Not Assigned(ModalCode) Then
CloseWindow
Else
If CanClose Then Begin
TransferData(tf_GetData);
EndDlg(id_Ok)
End
End;
Procedure tDialogWindow.Cancel (Var Msg: tMessage);
Begin
EndDlg(id_Cancel)
End;
Procedure tDialogWindow.wmClose (Var Msg: tMessage);
Begin
EndDlg(id_Cancel)
End;
Procedure tDialogWindow.wmQueryEndSession (Var Msg: tMessage);
Begin
If Assigned(ModalCode) Then
If @Self=Application^.MainWindow Then
Msg.Result:= Integer(Not Application^.CanClose)
Else
Msg.Result:= Integer(Not CanClose)
Else
Inherited wmQueryEndSession(Msg)
End;
Procedure tDialogWindow.wmSize (Var Msg: tMessage);
Begin
Inherited wmSize(Msg);
If Assigned(Scroller) Then With Scroller^ Do Begin
AutoOrg:= Msg.wParam<>sizeIconic;
If AutoOrg Then Begin
With DialogAttr, Attr Do
SetRange(ResW-W, ResH-H);
ScrollTo(0, 0);
XLine:= XPage Div 4;
YLine:= YPage Div 4;
InvalidateRect(hWindow, Nil, True)
End
End
End;
Procedure tDialogWindow.wmLButtonDown (Var Msg: tMessage);
Begin
HideComboListBox;
Inherited wmLButtonDown(Msg)
End;
Procedure tDialogWindow.wmNcLButtonDown (Var Msg: tMessage);
Begin
HideComboListBox;
{$IfDef Custom} Inherited wmNcLButtonDown(Msg) {$Else} DefWndProc(Msg) {$EndIf}
End;
Procedure tDialogWindow.wmEnterMenuLoop (Var Msg: tMessage);
Begin
HideComboListBox;
DefWndProc(Msg)
End;
Procedure tDialogWindow.wmActivate (Var Msg: tMessage);
Begin
Inherited wmActivate(Msg);
If Msg.wParam<>0 Then
InvalidateRect(hWindow, Nil, True);
{-this fixes an OWL bug when the last MDI child is closed}
If (Msg.wParam=0) And (Application^.kbHandlerWnd=@Self) Then
Application^.SetKBHandler(Nil)
End;
Procedure tDialogWindow.HideComboListBox;
Begin
SendMessage(FocusChildHandle, cb_ShowDropDown, 0, 0);
SendMessage(GetParent(FocusChildHandle), cb_ShowDropDown, 0, 0);
End;
Procedure tDialogWindow.wmNextDlgCtl (Var Msg: tMessage);
Var
OldFocus, NewFocus: hWnd;
Begin
OldFocus:= FocusChildHandle;
If Msg.lParamLo=0 Then Begin
If OldFocus=0 Then Begin
{-set focus to the first tab item}
NewFocus:= 0;
OldFocus:= hWindow
End Else
If IsChild(hWindow, OldFocus) Then
NewFocus:= GetNextDlgTabItem(hWindow, OldFocus, WordBool(Msg.wParam))
Else
Exit {ignore message if current focus is not a dialog ctl}
End Else Begin
If OldFocus=0 Then
OldFocus:= hWindow;
NewFocus:= Msg.wParam
End;
FocusChildHandle:= NewFocus;
FocusChild;
Msg.Result:= 0
End;
Procedure tDialogWindow.dmGetDefId (Var Msg: tMessage);
Begin
If DefId=0 Then
Msg.Result:= 0
Else Begin
Msg.ResultLo:= DefId;
Msg.ResultHi:= dc_HasDefId
End
End;
Procedure tDialogWindow.wmGetFont (Var Msg: tMessage);
Begin
Msg.Result:= DialogAttr.Font
End;
Procedure tDialogWindow.wmSetFocus (Var Msg: tMessage);
Begin
If IsFlagSet(wb_KBHandler) And Not IsIconic(hWindow) Then Begin
Application^.SetKBHandler(@Self);
FocusChild;
End Else
Application^.SetKBHandler(Nil);
Msg.Result:= 0
End;
Procedure tDialogWindow.wmCtlColor (Var Msg: tMessage);
Begin
If DlgStyle And EnableCtl3D<>0 Then With Msg Do Begin
Result:= dCtl3D.CtlColorEx(Message, wParam, lParam);
If Result<>0 Then
Exit
End;
DefWndProc(Msg)
End;
Procedure tDialogWindow.wmEraseBkGnd (Var Msg: tMessage);
Var
aBrush,
OldBrush: hBrush;
aRect: tRect;
aPoint: tPoint;
Begin
aBrush:= 0;
If Not IsBorDlg And (DlgStyle And EnableCtl3D<>0) Then
With Msg Do
aBrush:= dCtl3D.CtlColorEx(CtlColor_Dlg, wParam, MakeLong(0, CtlColor_Dlg));
If DlgStyle And (ForceGrayBk Or GrayBorDlg)<>0 Then
aBrush:= GetStockObject(LtGray_Brush);
If (aBrush=0) And IsBorDlg Then
aBrush:= dBWCC.GetPattern;
If aBrush<>0 Then Begin
GetClientRect(hWindow, aRect);
aPoint.x:= aRect.left; aPoint.y:= aRect.top;
ClientToScreen(Msg.wParam, aPoint);
UnrealizeObject(aBrush);
SetBrushOrg(Msg.wParam, (aPoint.x+1) Mod 7, aPoint.y Mod 7);
OldBrush:= SelectObject(Msg.wParam, aBrush);
With aRect Do PatBlt(Msg.wParam, left, top, right-left, bottom-top, PatCopy);
SelectObject(Msg.wParam, OldBrush);
Msg.Result:= 1
End Else
DefWndProc(Msg)
End;
Procedure tDialogWindow.wmTrackFocus (Var Msg: tMessage);
Var
aRect,
ClientRect: tRect;
dX, dY: Integer;
Begin
FocusChildHandle:= Msg.wParam;
If Not IsIconic(hWindow) And Assigned(Scroller) And Scroller^.AutoMode Then Begin
GetWindowRect(FocusChildHandle, aRect);
GetClientRect(hWindow, ClientRect);
MapWindowPoints(0, hWindow, aRect, 2); {Screen->hWindow}
With aRect, Scroller^ Do {test if control is outside the client area}
If (left<0) Or (right>ClientRect.right)
Or (top<0) Or (bottom>ClientRect.bottom) Then Begin
{-try to center the control in the client area}
dX:= (ClientRect.right-(right-left)) Div 2; If dX<0 Then dX:= 0;
dY:= (ClientRect.bottom-(bottom-top)) Div 2; If dY<0 Then dY:= 0;
ScrollTo((left-dX+XPos*XUnit) Div XUnit, (top-dY+YPos*YUnit) Div YUnit)
End
End
End;
Procedure tDialogWindow.wmVbxFireEvent (Var Msg: tMessage);
Begin
If Not EventPerform(@Self, pVbxEvent(Msg.lParam)^, id_First+pVbxEvent(Msg.lParam)^.Id) Then
DefaultEventProc(pVbxEvent(Msg.lParam)^);
Msg.Result:= 0
End;
Procedure tDialogWindow.DefaultEventProc (Var Event: tVbxEvent);
Begin
With Event Do If GetObjectPtr(Window)<>Nil Then {route to object}
SendMessage(Window, wm_VbxFireEvent, 0, LongInt(@Event))
End;
Function ExecDialogWindow (aDialogWindow: pDialogWindow): Integer;
Var
ExecReturn: Integer;
Begin
ExecDialogWindow:= id_Cancel;
If Application^.ValidWindow(aDialogWindow)<>Nil Then Begin
ExecReturn:= aDialogWindow^.RunModal;
If ExecReturn<0 Then
Application^.Error(ExecReturn)
Else
ExecDialogWindow:= ExecReturn
End
End;
Function tAdvApplication.ProcessDlgMsg (Var Message: tMsg): Boolean;
Var
hKbdWnd,
hFocus: tHandle;
Begin
ProcessDlgMsg:= False;
If KBHandlerWnd=Nil Then Exit;
hKbdWnd:= KBHandlerWnd^.hWindow;
If hKbdWnd=0 Then Exit;
{If (Message.Message=wm_KeyDown) And (Message.wParam=vk_Return) Then Begin
hFocus:= GetFocus;
If IsChild(hKbdWnd, hFocus)
And (SendMessage(hFocus, wm_GetDlgCode, 0, 0) And DlgC_HasSetSel<>0) Then
Message.wParam:= vk_Tab;
End;}
If Not IsDialogMessage(hKbdWnd, Message) Then Exit;
ProcessDlgMsg:= True;
If IsWindow(hKbdWnd) And Not IsIconic(hKbdWnd) Then Begin
hFocus:= GetFocus;
If IsChild(hKbdWnd, hFocus)
And (pWindow(KBHandlerWnd)^.FocusChildHandle<>hFocus) Then
SendMessage(hKbdWnd, wm_TrackFocus, hFocus, 0)
End
End;
Function tAdvApplication.ProcessAppMsg (Var Message: tMsg): Boolean;
Const
MdiTest: (NotTested, IsMdi, IsNotMdi) = NotTested;
Begin
If (MdiTest=NotTested) And Assigned(MainWindow) Then
If MainWindow^.GetClient=Nil Then
MdiTest:= IsNotMdi
Else
MdiTest:= IsMdi;
If MdiTest=IsMdi Then
ProcessAppMsg:= ProcessMDIAccels(Message)
Or ProcessAccels(Message)
Or ProcessDlgMsg(Message)
Else
ProcessAppMsg:= ProcessDlgMsg(Message)
Or ProcessMDIAccels(Message)
Or ProcessAccels(Message)
End;
Procedure tAdvMdiWindow.wmActivate (Var Msg: tMessage);
Var
TopWnd: hWnd;
Begin
Inherited wmActivate(Msg);
If (Msg.wParam<>0) And Assigned(ClientWnd) Then Begin
TopWnd:= LoWord(SendMessage(ClientWnd^.hWindow, wm_MdiGetActive, 0, 0));
If TopWnd<>0 Then
SendMessage(TopWnd, wm_Activate, wa_Active, 0)
End
End;
End.